package cn.itcast.order.thread;

import cn.itcast.order.mapper.OrderMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

import java.lang.management.ManagementFactory;
import java.lang.management.ThreadMXBean;

@Slf4j
@Component
public class DatabaseOperationExample implements ApplicationRunner {

    @Autowired
    private OrderMapper orderMapper;

    @Override
    public void run(ApplicationArguments args) throws Exception {
        log.info("start task");
        // 获取线程管理 MXBean
        ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
        // 启用线程 CPU 时间测量
        if (threadMXBean.isThreadCpuTimeSupported()) {
            threadMXBean.setThreadCpuTimeEnabled(true);
        } else {
            System.out.println("线程 CPU 时间测量不受支持");
            return;
        }

        // 创建并启动示例线程
        Thread dbThread = new Thread(new DatabaseTask(threadMXBean));
        dbThread.start();

        try {
            // 等待线程完成
            dbThread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        log.info("finish task");
    }


    class DatabaseTask implements Runnable {
        private final ThreadMXBean threadMXBean;
        public DatabaseTask(ThreadMXBean threadMXBean) {
            this.threadMXBean = threadMXBean;
        }
        @Override
        public void run() {
            long threadId = Thread.currentThread().getId();
            // 记录开始的 CPU 时间
            long startCpuTime = threadMXBean.getThreadCpuTime(threadId);
            // 服务时间：模拟计算任务
            performComputation();
            // 记录计算后的 CPU 时间
            long afterComputationCpuTime = threadMXBean.getThreadCpuTime(threadId);
            // 等待时间：执行数据库查询
            performDatabaseQuery();
            // 记录结束的 CPU 时间
            long endCpuTime = threadMXBean.getThreadCpuTime(threadId);
            // 计算服务时间和等待时间（纳秒）
            long computationCpuTime = afterComputationCpuTime - startCpuTime;
            long databaseQueryCpuTime = endCpuTime - afterComputationCpuTime;
            long totalCpuTime = endCpuTime - startCpuTime;
            log.info("计算任务的 CPU 时间 (ms): {}", computationCpuTime / 1_000_000);
            log.info("数据库查询的 CPU 时间 (ms): {}", databaseQueryCpuTime / 1_000_000);
            log.info("总的 CPU 时间 (ms): {}", totalCpuTime / 1_000_000);
        }

        private void performComputation() {
            // 模拟计算任务
            long sum = 0;
            for (int i = 0; i < 10000000; i++) {
                sum += i;
            }
            log.info("计算结果: {}", sum);
        }

        private void performDatabaseQuery() {
            orderMapper.findById(101L);
        }
    }

}
